// Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{str::FromStr, sync::Arc};

use lazy_static::lazy_static;
use log::error;
use maestro_derive::MsgTag;
use ohmw_derive::{Decode, Encode};
use tokio::{sync::Mutex, task::JoinHandle};

lazy_static! {
    static ref ROS1_DEPLOY_THREAD: Arc<Mutex<Option<JoinHandle<()>>>> = Arc::new(Mutex::new(None));
}

pub enum DeployContextKind {
    Ros1,
    Ros2,
    Dora,
}

#[derive(Encode, Decode, MsgTag)]
#[msg_tag(case = "snake_case")]
pub struct DeployContextRet {
    pub progress: f32,
    pub message: String,
}

impl FromStr for DeployContextKind {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ros1" => Ok(DeployContextKind::Ros1),
            "ros2" => Ok(DeployContextKind::Ros2),
            "dora" => Ok(DeployContextKind::Dora),
            _ => Err(format!("unknown deploy context kind {}", s)),
        }
    }
}

pub async fn deploy_context(kind: DeployContextKind, start: bool) {
    match kind {
        DeployContextKind::Ros1 => {
            if start {
                if ROS1_DEPLOY_THREAD.lock().await.as_ref().is_some_and(|h| !h.is_finished()) {
                    error!("ros1 deploy context already running");
                    return;
                }

                *ROS1_DEPLOY_THREAD.lock().await = Some(tokio::spawn(deploy_ros1_context()));
            } else {
                if let Some(h) = ROS1_DEPLOY_THREAD.lock().await.take() {
                    h.abort();
                }
            }
        },
        DeployContextKind::Ros2 => error!("ros2 not supported yet"),
        DeployContextKind::Dora => error!("dora not supported yet"),
    }
}

async fn deploy_ros1_context() {
    todo!()
}
